package jwt

import (
	"context"
	"errors"
	"git.myscrm.cn/golang/common/uuid"
	"github.com/dgrijalva/jwt-go"
	"time"
)

// 一些常量
var (
	RpaTokenExpired     = errors.New("token is expired")
	RpaTokenNotValidYet = errors.New("token not active yet")
	RpaTokenMalformed   = errors.New("that's not even a token")
	RpaTokenInvalid     = errors.New("couldn't handle this token")
)

const (
	RPA_DEFAULT_SINGKEY = "7264daa3-0cdb-11ed-8246-043f72e4f15a"
	RPA_AUTH_INFO       = "RPA_AUTH_INFO"
)

type RpaJWT struct {
	SigningKey []byte
}

var DefaultRpaJWT = &RpaJWT{SigningKey: []byte(RPA_DEFAULT_SINGKEY)}

// RpaClaims jwt编码字段
type RpaClaims struct {
	//租户code
	TenantCode string `json:"t"`
	//用户编码
	UserId string `json:"u"`
	jwt.StandardClaims
}

// 上下文获取Rpa认证信息
func GetAuthInfo(ctx context.Context) (*RpaClaims, error) {
	authInfoInter := ctx.Value(RPA_AUTH_INFO)
	authInfo, ok := authInfoInter.(*RpaClaims)
	if !ok {
		return nil, errors.New("无认证信息")
	}

	return authInfo, nil
}

// GenerateRpaToken
func (j *RpaJWT) GenerateRpaToken(tenantCode, tenantUserCode string) (string, error) {
	j.SigningKey = []byte(RPA_DEFAULT_SINGKEY)
	claims := RpaClaims{
		tenantCode,
		tenantUserCode,
		jwt.StandardClaims{
			NotBefore: time.Now().Unix() - 1000,
			IssuedAt:  time.Now().Unix(),
			//ExpiresAt: time.Now().Unix() + 3600,
			Issuer: "ycg-gfyx-rpa",
			Id:     uuid.GetUUID(),
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString(j.SigningKey)
	return tokenString, err
}

// ParseRpaToken 解析主应用token
func (j *RpaJWT) ParseRpaToken(tokenString string) (*RpaClaims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &RpaClaims{}, func(token *jwt.Token) (interface{}, error) {
		return j.SigningKey, nil
	})

	if err != nil {
		return nil, err
	}

	if claims, ok := token.Claims.(*RpaClaims); ok && token.Valid {
		return claims, nil
	}

	return nil, RpaTokenInvalid
}
